home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 526-550 / disk_531 / disdf / disdf.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  11KB  |  475 lines

  1.  
  2. /* DisDF.c V1.0    Disables DF0-DF3                                       */
  3. /* Patrick F. Misteli 22.7.91                                             */
  4. /* see DisDF.doc and 'usage' below                                        */
  5.  
  6. #define ND 4                                         /* max floppy drives */
  7. #define NN 100                                   /* max tasknodes to scan */
  8. #define DISABLEDP -123                       /* priority of disabled task */
  9. #define BUSYPRI   -122
  10. #define mTS_WAIT    4                        /* manx 3.4b has 4L for this */
  11. #define mTS_REMOVED 6
  12.  
  13. #include <exec/types.h>
  14. #include <exec/exec.h>
  15. #include <exec/execbase.h>
  16. #include <exec/memory.h>
  17. #include <exec/tasks.h>
  18. #include <stdio.h>
  19.  
  20. #include <devices/trackdisk.h>
  21. #include <exec/devices.h>
  22. #include <exec/io.h>
  23.  
  24. #include <dos.h>                           /* LATTICE is defined in dos.h */
  25.       /* manx 3.4b doesn't have dos.h so add one with AZTEC defined in it */
  26.  
  27. #ifdef LATTICE
  28. #include <proto/exec.h>
  29.  
  30. #else
  31. #ifdef AZTEC
  32. struct IORequest *CreateExtIO();
  33. struct MsgPort *CreatePort();
  34. #include <functions.h>
  35.  
  36. #else
  37. #define OTHER_COMPILER 1
  38. struct IORequest *CreateExtIO();
  39. struct MsgPort *CreatePort();
  40. struct Task *DeviceProc();
  41. struct Task *FindTask();
  42. long SetTaskPri();
  43. long Signal();
  44. char *AllocMem();
  45. struct Task *CreateTask();
  46. #endif
  47. #endif
  48.  
  49. extern struct ExecBase *SysBase;
  50.  
  51. char extioerrmsg[]  = "DisDF CreateExtIO() error";
  52. char creatportmsg[] = "DisDF CreatePort() error";
  53. char nofloppymsg[]  = "DisDF no floppy drive found";
  54. char notmountmsg[]  = "DisDF DFi not mounted";
  55. char missingdmsg[]  = "DisDF DFi device process missing";
  56. char missingtmsg[]  = "DisDF DFi trackdisk.device task missing";
  57. char missingfmsg[]  = "DisDF DFi File Process task missing";
  58. char memerrormsg[]  = "DisDF not enough memory";
  59. char statusokmsg[]  = "DisDF DFi trackdisk oxx File System oxx";
  60. char statusermsg[]  = "DisDF DFi error";
  61. char busytaskmsg[]  = "DisDF BusyLoop-122 running";
  62.  
  63. char *usagemsg[] =
  64. {
  65.  "\nDisDF V1.0 toggles floppy drives' trackdisk.device tasks off or on\n",
  66.  "usage : DisDF [0] [1] [2] [3] [-d|e] [-f] [-h]",
  67.  "         #  drive number if not all DF0: to DF3:",
  68.  "        -c  change priorities and start busyloop task",
  69.  "        -d  disable instead of toggle",
  70.  "        -e  enable  instead of toggle",
  71.  "        -f  disable floppy drives' File System tasks also",
  72.  "        -h  help message to stdout",
  73.  "        -s  status message to stdout only, tasks not changed",
  74.  "        -v  verbose",
  75.  NULL
  76. };
  77.  
  78. char trackdisk[]  = TD_NAME;                        /* "trackdisk.device" */
  79. char filesystem[] = "File System";
  80. char dfstr[] = "DF0:";
  81. char busyname[] = "BusyLoop-122";
  82.  
  83. struct Task *me;
  84. struct Node *fnode[ ND ], *tnode[ ND ];
  85. struct Task *busytask;
  86. int drive[ ND ], statusonly, chicken;
  87. long previouspri;
  88.  
  89. main( argc, argv )
  90. int argc;
  91. char *argv[];
  92. {
  93.  register int i;
  94.  register struct Node *np;
  95.  register int j, k;
  96.  struct Node *anode[ NN ];
  97.  int all, en, ds, fs, verbose;
  98.  long failval;
  99.  struct MsgPort *diskport;
  100.  struct IOExtTD *ioexttd;
  101.  
  102.  failval = 0L;
  103.  all = TRUE;
  104.  en = ds = fs = verbose = statusonly = chicken = FALSE;
  105.  for ( i = 0; i < ND; i++ )
  106.  {
  107.   drive[i] = FALSE;
  108.   tnode[i] = NULL;
  109.   fnode[i] = NULL;
  110.  }
  111.  
  112.  if ( argc > 1 )
  113.  {
  114.   for ( i = 1; i < argc; i++ )
  115.   {
  116.    switch ( *argv[i] )
  117.    {
  118.     case '-':
  119.      if ( argv[ i ][ 2 ] )
  120.            usageexit();
  121.      switch( argv[ i ][ 1 ])
  122.      {
  123.       case 'c':
  124.        chicken = TRUE;
  125.       break;
  126.       case 'd':
  127.        if ( en )
  128.         usageexit();
  129.        ds = TRUE;
  130.       break;
  131.       case 'e':
  132.        if ( ds )
  133.         usageexit();
  134.        en = TRUE;
  135.       break;
  136.       case 'f':
  137.        fs = TRUE;
  138.       break;
  139.       case 's':
  140.        statusonly = TRUE;
  141.       break;
  142.       case 'v':
  143.        verbose = TRUE;
  144.       break;
  145.       default :
  146.        usageexit();
  147.       break;
  148.      }
  149.     break;
  150.     case '0' :
  151.     case '1' :
  152.     case '2' :
  153.     case '3' :
  154.      if ( argv[i][1] != 0 )
  155.       usageexit();
  156.      drive[ *argv[i] - 48 ] = TRUE;
  157.      all = FALSE;
  158.     break;
  159.     default:
  160.      usageexit();
  161.     break;
  162.    } /* switch   */
  163.   } /* for i    */
  164.  } /* argc > 1 */
  165.  
  166.  if ( all )
  167.   drive[0] = drive[1] = drive[2] = drive[3] = TRUE;
  168.  
  169.  me = FindTask( 0L );
  170.  previouspri = SetTaskPri( me, -1L ); /* allow most other tasks to finish */
  171.  Forbid();                        /* before grabbing the CPU until exit() */
  172.  
  173.               /* find out which drives are mounted by trying to open them */
  174.  diskport = CreatePort( 0, 0 );
  175.  if( diskport == NULL )
  176.  {
  177.   puts( creatportmsg );
  178.   permexit( 11 );
  179.  }
  180.  ioexttd = (struct IOExtTD *)CreateExtIO( diskport,
  181.                                             (long)sizeof(struct IOExtTD ) );
  182.  if( ioexttd == 0 )
  183.  {
  184.   puts( extioerrmsg );
  185.   DeletePort( diskport );
  186.   permexit( 12L );
  187.  }
  188.  for ( i = 0; i < ND; i++ )
  189.  {
  190.   if ( drive[i] )
  191.    if ( !OpenDevice( trackdisk, (long)i, (struct IORequest *)ioexttd, 0L ) )
  192.    {                          /* get pointer to its trackdisk.device task */
  193.     tnode[i] =
  194.            (struct Node *)ioexttd->iotd_Req.io_Unit->unit_MsgPort.mp_SigTask;
  195.     CloseDevice( (struct IORequest *)ioexttd );
  196.    }
  197.  }
  198.  DeleteExtIO( (struct IORequest *)ioexttd, sizeof( struct IOExtTD ) );
  199.  DeletePort( diskport );
  200.  
  201.  if ( all )                    /* check that at least one drive was found */
  202.  {
  203.   for ( i = 0; i < ND; i++ )
  204.    if ( tnode[i] )
  205.     break;
  206.   if ( i >= ND )
  207.   {
  208.    puts( nofloppymsg );
  209.    permexit( 13L );
  210.   }
  211.  }
  212.  else
  213.  {
  214.   for ( i = 0; i < ND; i++ )     /* check for drives specified in command */
  215.    if ( !tnode[i] )
  216.     if ( drive[i] )
  217.     {
  218.      notmountmsg[8] = 48 + i;
  219.      puts( notmountmsg );   
  220.     }
  221.  }
  222.  
  223.  for ( i = 0; i < ND; i++ ) /* find each mounted drive's File System task */
  224.  {
  225.   if ( tnode[i] )
  226.   {
  227.    dfstr[2] = 48 + i;
  228.    fnode[i] = (struct Node *)DeviceProc( dfstr );
  229.    if ( fnode[i] )
  230.     fnode[i] = (struct Node *)( (long)fnode[i] - sizeof(struct Task) );
  231.    else
  232.    {
  233.     tnode[i] = NULL;
  234.     missingdmsg[8] = 48 + i;
  235.     puts( missingdmsg );
  236.     failval += 1L << (i + 4);
  237.    }
  238.   }
  239.  }
  240.             /* ensure that the tasks found above are in exec's task lists */
  241.  for ( i = 0; i < NN; i++ )
  242.   anode[i] = NULL;
  243.  i = 0;
  244.  Disable();
  245.  for ( np = (struct Node *)SysBase->TaskReady.lh_Head; i < NN, np->ln_Succ;
  246.                                                           np = np->ln_Succ )
  247.   anode[i++] = np;
  248.  for ( np = (struct Node *)SysBase->TaskWait.lh_Head;  i < NN, np->ln_Succ;
  249.                                                           np = np->ln_Succ )
  250.   anode[i++] = np;
  251.  Enable();
  252.  for ( i = 0; i < ND; i++ )
  253.  {
  254.   if ( tnode[i] )
  255.   {
  256.    for ( j = 0; j < NN; j++ )
  257.     if ( tnode[i] == anode[j] )
  258.      break;
  259.    if ( j >= NN )          /* if the task is not there, ignore this drive */
  260.    {
  261.     tnode[i] = NULL;
  262.     fnode[i] = NULL;
  263.     missingtmsg[8] = 48 + i;
  264.     puts( missingtmsg );
  265.     failval += 1L << (i + 8);
  266.    }
  267.   }
  268.   if ( fnode[i] )
  269.   {
  270.    for ( j = 0; j < NN; j++ )
  271.     if ( fnode[i] == anode[j] )
  272.      break;
  273.    if ( j >= NN )
  274.    {
  275.     tnode[i] = NULL;
  276.     fnode[i] = NULL;
  277.     missingfmsg[8] = 48 + i;
  278.     puts( missingfmsg );
  279.     failval += 1L << (i + 12);
  280.    }
  281.   }
  282.  }
  283.  
  284.  if ( statusonly )
  285.  {
  286.   typestatus();
  287.   permexit();
  288.  }
  289.  
  290.  if ( !chicken )
  291.  {
  292.   Disable();           /* remove tasks found above from exec's task lists */
  293.   for ( i = 0; i < ND; i++ )
  294.    if( tnode[i] )
  295.    {
  296.     Remove( tnode[i] );
  297.     Remove( fnode[i] );
  298.    }
  299.   Enable();
  300.  }
  301.  
  302.  for ( i = j = 0; i < ND; i++ )                        /* modify priority */
  303.  {
  304.   if ( tnode[i] )
  305.   {
  306.    if ( en || ( ( tnode[i]->ln_Pri == DISABLEDP ) && !ds )  )
  307.    {
  308.     modtask( tnode[i], 5 );
  309.     modtask( fnode[i], 10 );
  310.    }
  311.    else
  312.    {
  313.     modtask( tnode[i], DISABLEDP );
  314.     if ( fs )
  315.      modtask( fnode[i], DISABLEDP );
  316.     else
  317.      modtask( fnode[i], 10 );
  318.    }
  319.   }
  320.  }
  321.  
  322.  if ( !chicken )
  323.  {
  324.   Disable();                   /* put modified tasks back in exec's lists */
  325.   for ( i = 0; i < ND; i++ )
  326.    if( tnode[i] )
  327.    {
  328.     if ( tnode[i]->ln_Pri == DISABLEDP )
  329.     {
  330.      AddTail( &SysBase->TaskWait, tnode[i] );
  331.      AddTail( &SysBase->TaskWait, fnode[i] );
  332.     }
  333.     else
  334.     {
  335.      AddTail( &SysBase->TaskReady, tnode[i] );
  336.      AddTail( &SysBase->TaskReady, fnode[i] );
  337.     }
  338.    }
  339.   Enable();
  340.  }
  341.  
  342.  if ( busytask = FindTask( busyname ) )          /* maybe remove busytask */
  343.  {
  344.   for ( i = j = k = 0; i < ND; i++ )
  345.    if ( tnode[i] )
  346.     if ( tnode[i]->ln_Pri == DISABLEDP )
  347.     {
  348.      j++;
  349.      if ( ((struct Task*)tnode[i])->tc_State != mTS_REMOVED )
  350.       k++;
  351.     }
  352.     else         /* previously removed tasks in the wait list need a nudge */
  353.     {
  354.      Signal( (struct Task *)tnode[i],
  355.                                     ((struct Task *)tnode[i])->tc_SigAlloc );
  356.      Signal( (struct Task *)fnode[i],
  357.                                     ((struct Task *)fnode[i])->tc_SigAlloc );
  358.     }
  359.   if ( !j || ( !chicken && k ) )
  360.    rembusytask();
  361.  }
  362.  else                                               /* maybe add busytask */
  363.  {
  364.   if ( chicken )
  365.    for ( i = 0; i < ND; i++ )
  366.     if ( tnode[i] )
  367.      if ( tnode[i]->ln_Pri == DISABLEDP )
  368.       break;;
  369.   if ( i <  ND )
  370.    addbusytask();
  371.  }
  372.  if ( verbose )
  373.   typestatus();
  374.  permexit( failval );
  375. } /* main */
  376.  
  377. usageexit()
  378. {
  379.  register int i;
  380.  for ( i = 0; usagemsg[i][0]; i++ )
  381.   puts( usagemsg[i] );
  382.  exit( 10 );
  383. }
  384.  
  385. modtask( task, pri )                  /* modifies task state and priority */
  386. struct Task *task;
  387. int pri;
  388. {
  389.  task->tc_State = mTS_WAIT;
  390.  if ( ( ((struct Node *)task)->ln_Pri = pri ) == DISABLEDP )
  391.   if ( !chicken )
  392.    task->tc_State = mTS_REMOVED;
  393. }
  394.  
  395. typestatus()
  396. {
  397.  register int i;
  398.  for ( i = 0; i < ND; i++ )
  399.  {
  400.   if ( !drive[i] )
  401.    continue;
  402.   if ( tnode[i] )
  403.   {
  404.    statusokmsg[8]  = i + 48;
  405.    if ( tnode[i]->ln_Pri == DISABLEDP )
  406.    {
  407.     statusokmsg[21] = 'f';
  408.     statusokmsg[22] = 'f';
  409.    }
  410.    else
  411.    {
  412.     statusokmsg[21] = 'n';
  413.     statusokmsg[22] = ' ';
  414.    }
  415.    if ( fnode[i]->ln_Pri == DISABLEDP )
  416.    {
  417.     statusokmsg[37] = 'f';
  418.     statusokmsg[38] = 'f';
  419.    }
  420.    else
  421.    {
  422.     statusokmsg[37] = 'n';
  423.     statusokmsg[38] = ' ';
  424.    }
  425.    puts( statusokmsg );
  426.   }
  427.   else
  428.    if ( !statusonly )
  429.    {
  430.     statusermsg[8] = i + 48;
  431.     puts( statusermsg );
  432.    }
  433.  } /* for i */
  434.  if ( FindTask( busyname ) )
  435.   puts( busytaskmsg );
  436. } /* typestatus */
  437.  
  438. permexit( exitval )                 /* all exits after Forbid() come here */
  439. long exitval;
  440. {
  441.  SetTaskPri( me, previouspri );    /* otherwise the CLI or WB stays at -1 */
  442.  Permit();               /* SetTaskPri() reschedules Forbidden tasks ?... */
  443.  exit( exitval );
  444. }
  445.  
  446. addbusytask()                  /* starts a busyloop task at priority -122 */
  447. {
  448.  char *busycode;
  449.  if ( !( busycode = AllocMem( 32L, MEMF_CLEAR ) ) )
  450.  {
  451.   puts( memerrormsg );
  452.   exit( 14 );
  453.  }
  454.  busycode[0] = 0x60; busycode[1] = 0xfe;                   /* kk:  BRA kk */
  455.  CopyMemQuick( busyname, busycode + 2, 12L );
  456.  if ( !( busytask =
  457.                CreateTask( busycode + 2, (long)BUSYPRI, busycode, 128L ) ) )
  458.  {
  459.   FreeMem( busycode, 32L );
  460.   puts( memerrormsg );
  461.   exit( 14 );
  462.  }
  463.  busytask->tc_UserData = (APTR)busycode;
  464. }
  465.  
  466. rembusytask()
  467. {
  468.  char *busycode;
  469.  busycode = (char *)busytask->tc_UserData;
  470.  DeleteTask( busytask );
  471.  FreeMem( busycode, 32L );
  472. }
  473.  
  474. /* fin DisDF.c */
  475.